/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \brief to make tof correction for f4
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2023-12-14
  \date 2023-12-14 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2023-12-14   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <iostream>
#include "TFile.h"
#include "TTree.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TClonesArray.h"
#include "TCanvas.h"
#include "ETFPlaHit.h"

using std::cout;
using std::endl;
using std::flush;

struct mtdc_t{
  unsigned n_hit;
  unsigned hit[2];
  void init(){
    n_hit = 0;
    hit[0] = -1; hit[1] = 0;
  }
};

static const double BLIP = 3.90625e-3; // ps

int main(int argc, char *argv[]){
  if(argc < 3){
    cout << "Illegal input. Follow the syntax below:" << endl;
    cout << "./f4 <f1_rootfile> <f4_rootfile>" << endl;
  } // end if
  TFile *f1 = new TFile(argv[1]);
  TFile *f4 = new TFile(argv[2]);
  TTree *etf = (TTree *)f1->Get("etf");
  TTree *tree4 = (TTree *)f4->Get("trigger");
  // etf->AddFriend(tree4);

  // assign the F4 part //
  mtdc_t t0[4], t1[6];
  char name[128]{};
  for(int i = 0; i < 4; i++){ // t0: tstart
    sprintf(name, "frag_mtdc_crate00_slot17_ch00%d", i);
    tree4->SetBranchAddress(name, &t0[i]);
  } // end for over i
  for(int i = 0; i < 6; i++){ // t1: tstop
    sprintf(name, "frag_mtdc_crate00_slot17_ch00%d", i + 4);
    tree4->SetBranchAddress(name, &t1[i]);
  } // end for over i

  // assign the F1 part //
  TClonesArray *tstart4 = new TClonesArray("ETFPlaHit");
  TClonesArray *t0arr = new TClonesArray("ETFPlaHit");
  etf->SetBranchAddress("tstart4", &tstart4);
  etf->SetBranchAddress("t0arr", &t0arr);

  // define some histos //
  TH2F *halign = new TH2F("halign", "t0 ((0+1)-(2+3))/2 -- VME v.s. PXI",
    500, -4., 4., 500, -4., 4.);
  // define some histos //
  TH2F *htof_pos = new TH2F("htof_pos", "tof v.s. t0arr pos",
    52, -52., 52., 500, 0., 60.);

  // now we start the data loop //
  const int n = etf->GetEntriesFast();
  for(int j = 0; j < n; j++){
    // cout << "Event " << j << endl; // DEBUG
    for(auto &t : t0) t.init();
    for(auto &t : t1) t.init();
    tree4->GetEntry(j);
    etf->GetEntry(j);

    // determine fired status //
    // f4-daq part
    bool t0_fired = true;
    for(int i = 0; i < 4; i++) if(!t0[i].n_hit){
      t0_fired = false; break;
    } // end for over i
    bool t1_fired = true;
    for(int i = 0; i < 6; i++) if(!t1[i].n_hit){
      t1_fired = false; break;
    } // end for over i
    // f1-daq part
    const int n_t0_pxi_fired = tstart4->GetEntriesFast();
    const bool t0_pxi_fired = 2 == n_t0_pxi_fired;
    int n_t0arr_fired = 0;
    double t0arr_pos = 0.;
    for(TObject * b : *t0arr){
      ETFPlaHit *t = dynamic_cast<ETFPlaHit *>(b);
      // t->Print(); getchar(); // DEBUG
      if(t->GetFiredStatus() == 4){
        n_t0arr_fired++;
        t0arr_pos += t->x();
        // cout << n_t0arr_fired << " " << t->x() << endl; // DEBUG
      } // end if
    } // end for over t0arr strips
    if(n_t0arr_fired) t0arr_pos /= n_t0arr_fired;
    // determine effective event //
    const bool fired = t0_fired && t1_fired && t0_pxi_fired && n_t0arr_fired;
    if(!fired) continue;

    // extract physical variables //
    // pxi daq
    double t0_pxi_0 = dynamic_cast<ETFPlaHit *>(tstart4->At(0))->GetTime();
    double t0_pxi_1 = dynamic_cast<ETFPlaHit *>(tstart4->At(1))->GetTime();
    const double t0_lmr_pxi = t0_pxi_0 - t0_pxi_1;

    // f4 daq
    double t0_f4 = 0., t1_f4 = 0.;
    for(int i = 4; i--;) t0_f4 += t0[i].hit[0] * BLIP;
    t0_f4 /= 4.;
    for(int i = 6; i--;) t1_f4 += t1[i].hit[0] * BLIP;
    t1_f4 /= 6.;
    // tstop, i.e. t1
    const double tof = t1_f4 - t0_f4;
    const double t0_lmr_f4 =
      ((t0[0].hit[0]+t0[1].hit[0]) - (t0[2].hit[0]+t0[3].hit[0])) / 2. * BLIP;

    // fill the histos //
    halign->Fill(t0_lmr_pxi, t0_lmr_f4);
    htof_pos->Fill(t0arr_pos, tof);

    cout << "Processing event " << j << "\r" << flush;
  } // end for over events

  cout << "Totally " << n << " events conversioned. \033[32;1m:)\033[0m" << endl;
  cout << "The result has been stored in f4.root" << endl;
  TFile *f = new TFile("f4.root", "recreate");
  TCanvas *c = new TCanvas("c", "f4_f1 coorporation", 800, 1200);
  c->Divide(1,2);
  c->cd(1); halign->Draw("col");
  c->cd(2); htof_pos->Draw("col");
  halign->Write("", TObject::kOverwrite);
  htof_pos->Write("", TObject::kOverwrite);
  c->Write("", TObject::kOverwrite);
  f->Close();

  return 0;
} // end main function
